﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using GKFX.Common.Business.BOL.Common;
using Century.Model;
using System.Web;

using GKFX.Business.Repository;

namespace GKFX.Common.UI.Helpers
{
    /// <summary>
    /// Class to parse url for GKFX
    /// Site path is depend on Country Site Table
    /// </summary>
    public class UrlParser
    {

        #region [ Constructor(s) ]

        public UrlParser(string url)
        {
            Parse(new System.Uri(url));
        }

        public UrlParser(System.Uri uri)
        {
            Parse(uri);
        }

        #endregion

        #region [ Private Method(s) ]

        private void Parse(System.Uri uri)
        {
            // get the port  
            Port = uri.Port;

            // get the host name (my.domain.com)  
            Host = uri.Host;

            // get the protocol  
            Protocol = uri.Scheme;

            // get the domain and subdomain
            if (uri.AbsoluteUri.ToLower().Contains("localhost"))
            {
                Domain = "localhost";
            }
            else if (uri.HostNameType == UriHostNameType.IPv4 || uri.HostNameType == UriHostNameType.IPv6)
            {
                Domain = Host;
            }
            else
            {
                string subDomainPattern = @"^(?<subdomain>[\w\.\-]+\.)*(?<domain>[\w\-]+\.)(?<com>[\w]{2,3})(?<countryextension>\.[\w]{2})?$";
                Regex regex = new Regex(subDomainPattern);
                Match match1 = Regex.Match(uri.Host, subDomainPattern, RegexOptions.RightToLeft);
                if (match1.Success)
                {
                    SubDomain = match1.Groups["subdomain"].ToString();
                    Domain = match1.Groups["domain"].ToString() + match1.Groups["com"].ToString() + match1.Groups["countryextension"];
                }
            }

            if (Port == 80)
            {
                CleanURL = string.Format("{0}://{1}/", uri.Scheme, uri.GetComponents(UriComponents.Host, UriFormat.UriEscaped));
            }
            else
            {
                CleanURL = string.Format("{0}://{1}/", uri.Scheme, uri.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped));

            }

            // get site path
            string path = UrlPath = SitePath = string.Empty;
            if (uri.Segments.Length > 1)
            {
                path = uri.Segments[1].Replace("/", string.Empty);
            }
            //AvailableCountrySites = new CountrySiteBSO().GetAvailabeSites();
            
            if (!string.IsNullOrEmpty(path))
            {
                if (!PersistData.AvailableSites.Any(c => c.Path.ToLower() == path.ToLower()))
                {
                    path = string.Empty;
                }
                else
                {
                    UrlPath = path;
                }
            }

            if (string.IsNullOrEmpty(path))
            {
                HttpCookie cookie = HttpContext.Current.Request.Cookies[ConfManager.Instance.CookieManager.CountryCookieName.ConfigValue];
                if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
                {
                    path = cookie.Value;
                }
            }
            if (!string.IsNullOrEmpty(path))
            {
                CountrySite site = PersistData.AvailableSites.FirstOrDefault(c => c.Path.ToLower() == path.ToLower());
                if (site != null)
                {
                    SitePath = path;
                    //get real site address for current path
                    SiteAddress = site.SiteAddress;
                    if (System.Web.HttpContext.Current.Session == null)
                    {
                        HttpContext.Current.Response.Redirect(SiteAddress);
                        return;
                    }
                    System.Web.HttpContext.Current.Session["CurrentSiteId"] = site.Id;
                }

            }
            string postFix = string.Empty;
            if (uri.AbsolutePath.ToLower().Contains("/" + UrlPath.ToLower() + "/"))
            {
                postFix = "/";
            }
            CurrentAddress = CleanURL.ToLower().Replace("www.", string.Empty) + (string.IsNullOrEmpty(UrlPath) ? string.Empty : UrlPath + postFix);
            LocalPath = uri.LocalPath.Replace("/" + SitePath + "/", string.Empty);
            PathAndQuery = uri.PathAndQuery.ToLower().Replace("/" + SitePath.ToLower() + "/", string.Empty);
            if (PathAndQuery.ToLower() == "/" + SitePath.ToLower())
            {
                PathAndQuery = string.Empty;
            }
            if (PathAndQuery.ToLower().StartsWith("/" + SitePath.ToLower() + "?"))
            {
                PathAndQuery = PathAndQuery.ToLower().Replace("/" + SitePath.ToLower(), string.Empty);
            }
            if (PathAndQuery.StartsWith("/"))
            {
                PathAndQuery = PathAndQuery.Substring(1);
            }
            Query = uri.Query;
        }

        #endregion

        #region [ Propert(ies) ]

        public int Port { get; set; }

        public string Host { get; set; }

        public string Protocol { get; set; }

        public string CleanURL { get; set; }

        /// <summary>
        /// SitePath on Country Site Table
        /// </summary>
        public string SitePath { get; set; }

        /// <summary>
        /// Domain of url
        /// </summary>
        public string Domain { get; set; }

        /// <summary>
        /// Sub domain or sub domains of url
        /// </summary>
        public string SubDomain { get; set; }

        /// <summary>
        /// Site Address of a Site Path
        /// </summary>
        public string SiteAddress { get; set; }

        public string CurrentAddress { get; set; }

        public string UrlPath { get; set; }

        public string LocalPath { get; set; }

        public string PathAndQuery { get; set; }

        public string Query { get; set; }

        #endregion
    }
}
